home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / RGASM.RAR / ASMCODE.EXE / CHAPT9 / DSERV2.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-05-10  |  35.3 KB  |  777 lines

  1. ;********************************************************************
  2. ;
  3. ;  Program DServ ( Chapter 9 )
  4. ;
  5. ;  Diskette processing system ( OS independent)
  6. ;
  7. ;  Author:  Sopin A.I., Voronegh, 1990 --- 1993.      Version 3.0
  8. ;  ------                                             22/04/93 11:39
  9. ;
  10. ;  Floppy disks sectors reading/writing
  11. ;
  12. ;  The BIOS disk service (interrupt 13h) is used
  13. ;
  14. ;  Information is output onto the screen in two pages of 256 bytes each
  15. ;
  16. ;********************************************************************
  17. .model large
  18. EXTRN    DIAM00 : FAR, DIAM01 : FAR, CLEAR : FAR, DELAY : FAR, COLOR : FAR
  19. EXTRN    MOVE : FAR, HEXSYM : FAR, SYMIN4 : FAR, INSYM4 : FAR, SYMHEX : FAR
  20. ;
  21. ;  Save registers used
  22. PUSHR   MACRO   REGLST
  23.     IFB     <REGLST>
  24.     push    ax
  25.     push    bx
  26.     push    cx
  27.     push    dx
  28.     push    si
  29.     push    di
  30.     push    ds
  31.     push    es
  32.     push    bp
  33.     ENDIF
  34.     IRP     REG,<REGLST>
  35.     push    REG
  36.     ENDM
  37.     ENDM
  38. ;  Restore register used
  39. POPR    MACRO   REGLST
  40.     IFB     <REGLST>
  41.     pop     bp
  42.     pop     es
  43.     pop     ds
  44.     pop     di
  45.     pop     si
  46.     pop     dx
  47.     pop     cx
  48.     pop     bx
  49.     pop     ax
  50.     ENDIF
  51.     IRP     REG,<REGLST>
  52.     pop     REG
  53.     ENDM
  54.     ENDM
  55. ;  Call screen clearing subroutine and set up the screen color
  56. CLR     MACRO  M$,N$,C$
  57.     mov    ch,M$
  58.     mov    dh,N$
  59.     mov    ah,C$
  60.     Call   Color
  61.     ENDM
  62. ;
  63. DIAM0   MACRO   TEXT$,OP$,M$,N$,U$,V$
  64.     mov     TOFF,offset TEXT$    ;  address of text string
  65.     mov     OP,OP$               ;  operation mode
  66.     mov     M,M$                 ;  start line for output
  67.     mov     bx,N$                ;
  68.     mov     N,bx                 ;  last line for output
  69.     mov     U,U$                 ;  don't move cursor
  70.     mov     bx,V$                ;
  71.     mov     V,bx                 ;
  72.     lea     bx,PARM              ;
  73.     push    bx                   ;  address of parameters list for DIAM00
  74.     Call    DIAM00               ;
  75.     ENDM
  76. ;
  77. DIAM1   MACRO   TEXT$,OP$,M$,N$,U$,V$
  78.     mov     TOFF,offset TEXT$    ;  address of text string
  79.     mov     OP,OP$               ;  operation mode
  80.     mov     M,M$                 ;  start line for output
  81.     mov     bx,N$                ;
  82.     mov     N,bx                 ;  last line for output
  83.     mov     U,U$                 ;  don't move cursor
  84.     mov     bx,V$                ;
  85.     mov     V,bx                 ;
  86.     lea     bx,PARM              ;
  87.     push    bx                   ;  address of parameters list for DIAM00
  88.     Call    DIAM01               ;
  89.     ENDM
  90. ;
  91. ;  Clear the output buffer (filling with blanks)
  92. SPACE   MACRO   TXT$,L$
  93.     mov     ax,ds
  94.     mov     es,ax
  95.     lea     di,TXT$
  96.     mov     cx,L$
  97.     cld
  98.     mov     al,' '
  99.     rep     stosb
  100.     ENDM
  101. ;  Output number in hexadecimal representation
  102. HEX     MACRO   L$                       ;
  103.     Local   H1                       ;
  104.     mov     cx,L$                    ;  number of bytes
  105. H1:     mov     al,[si]                  ;
  106.     Call    HEXSYM                   ;  convert: HEX ---> SYM
  107.     mov     DS:[di],ax               ;
  108.     add     di,2                     ;
  109.     inc     si                       ;
  110.     loop    H1                       ;
  111.     ENDM
  112. ;----------------------------------------------------------
  113. .STACK   256
  114. .DATA
  115. ;
  116. TEXT0    db  ' Disk scanning needed?         ?  (Y / N )        ',0
  117. TEXT1    db  ' Diskette parameters:      Cylinders: ??     Heads: 00    '
  118.      db  'Sectors: ?? ',0
  119. TEXT2    db  ' Reading/modifying disk sectors        '
  120.      db  ' A.I.Sopin,  VSU  Voronezh  1991   ',0
  121. TEXT3    db  '    Drive: A     ',0
  122. TEXT4    db  '    Drive: A      Total:   Cylinders: xx     Heads: 00    '
  123.      db  'Sectors: xx ',0
  124. TEXT5    db  '                Address:    Cylinder: 00      Head: 00    '
  125.      db  ' Sector: 01 ',0
  126. Ltext5   EQU $-TEXT5-2
  127. TEXT6    db  ' Error while reading sector!  AH=xx  CC=xx  HH=xx  SS=xx '
  128.      db  ' ( press Enter  )    ',0
  129. TEXT7    db  ' Wrong diskette parameters specified - respecify.       ',0
  130. ;
  131. TEXT8    DB  ' Attention!  Disk is being scanned.  Please wait.      ',0
  132. TEXT9    db  ' Error while writing sector!  AH=xx  CC=xx  HH=xx  SS=xx '
  133.      db  ' ( press Enter  )    ',0
  134. I1       DB     53,1             ;  length =53, offset =1
  135.      DB     0,74h            ;  red letters on grey background
  136.      DW     0
  137. ;
  138. I2       DB     77,0             ;  length =77, offset =0
  139.      DB     0,74h            ;  red letters on grey background
  140.      DW     0
  141. ;
  142. TXT0     db  'Displacement ----------------- Hex codes -------------------'
  143.      db  '     ASCII value    ',0
  144. TXT25    db  ' PgDn -next  , PgUp -prev , Esc -exit , F3  -edit sector '
  145.      db  ', Enter -disk address', 0
  146. Ltxt25   EQU $-TXT25
  147. I25      DB     80,0              ;  length of field =80
  148.      DB     0,1Eh             ;  feature + yellow letters on blue 
  149.      DW     0                 ;  end of list  I
  150. ;
  151. Disp1    db  '0000(0000)','0016(0010)','0032(0020)','0048(0030)'
  152.      db  '0064(0040)','0080(0050)','0096(0060)','0112(0070)'
  153.      db  '0128(0080)','0144(0090)','0160(00A0)','0176(00B0)'
  154.      db  '0192(00C0)','0208(00D0)','0224(00E0)','0240(00F0)'
  155. Disp2    db  '0256(0100)','0272(0110)','0288(0120)','0304(0130)'
  156.      db  '0320(0140)','0336(0150)','0352(0160)','0368(0170)'
  157.      db  '0384(0180)','0400(0190)','0416(01A0)','0432(01B0)'
  158.      db  '0448(01C0)','0464(01D0)','0480(01E0)','0496(01F0)'
  159. ;
  160. BUFER    db     2000 dup (0)            ;
  161. RDBUF    db     512  dup (0)            ;
  162. ADRBUF   dw     0                       ;
  163. CC0      db     0                       ;  cylinder number (0...79)
  164. HH0      db     0                       ;  head number  (0  or 1)
  165. SS0      db     0                       ;  sector number  (1...15)
  166. Disk     db     0                       ;  drive number (0-A, 1-B...)
  167. Count3   db     0                       ;  counter of attemts to read 
  168. NCC0     db     0                       ;  maximum cylinder number (0 --- 79)
  169. NHH0     db     0                       ;  maximum head number   (0 --- 1)
  170. NSS0     db     0                       ;  maximum sector number  (1 --- 15)
  171. VV       dw     0                       ;  cursor position: CCHHSS
  172. NN       dw     0                       ;  line for output=6 (disk addres)
  173. MOD0     DB     0                       ;  indicates that CCHHSS was modified
  174. REG      DB     0                       ;  video mode
  175. ;
  176. ;  List of parameters for subroutines DIAM00 and DIAM01
  177.      EVEN
  178. PARM     LABEL  WORD                    ; parameter list (address in stack)
  179. OP       dw     0                       ; operation code
  180. M        dw     0                       ; number of first line
  181. N        dw     0                       ; number of last line
  182. TOFF     dw     0                       ; offset of text string
  183. L        dw     80                      ; length of text string
  184. U        dw     0                       ; row of cursor position  (1---25)
  185. V        dw     0                       ; column of cursor position (1---80)
  186. Q        dw     0                       ; accepted row of cursor
  187. S        dw     0                       ; accepted column of cursor
  188. W        dw  2 dup (0)                  ; code of interrupt key
  189. IOFF     dw     0                       ; address of screen parameters
  190. I        dw     80
  191.      db     0, 07h
  192. ;----------------------------------------------------------
  193. .CODE
  194. .Startup
  195.     mov     ah,0Fh                  ;
  196.     int     10h                     ;  read current video mode
  197.     mov     REG,al                  ;  save video mode
  198.     mov     IOFF,0                  ;  format list isn't used
  199.     CLR     1,24,07h                ;
  200.     CLR     25,25,1Eh               ;  yellow letters on blue
  201.     mov     IOFF,offset I25         ;
  202.     DIAM0   TXT25,1,25,25,0,0       ;  output prompt string
  203.     mov     IOFF,0                  ;
  204. ;  Output the header and ask for drive letter
  205. Addres: DIAM0   TEXT2,1,2,2,0,0         ;
  206.     DIAM0   TEXT3,3,4,-4,4,12       ;
  207.     and     TEXT3+11,0DFh           ;  force uppercase
  208.     mov     al,0                    ;  default drive A
  209.     cmp     TEXT3+11,'A'
  210.     je      M1                      ;  check for ESC pressed
  211.     mov     al,1                    ;  use drive B
  212.     cmp     TEXT3+11,'B'            ;
  213.     jne     Addres                  ;  invalid drive letter specified
  214. M1:     mov     Disk,al                 ;  drive number
  215.     cmp     byte ptr W,1bh          ;  Esc ?
  216.     jne     ScanD                   ;  ask for disk scanning
  217.     jmp     Exit                    ;
  218. ;----------------------------------------------------------
  219. ;  Ask for disk scanning to determine the diskette characterisics
  220. ScanD:  DIAM0   TEXT0,3,5,-5,5,32       ;
  221.     and     TEXT0+31,0DFh           ;  force uppercase
  222.     cmp     byte ptr W,1bh          ;  Esc ?
  223.     jne     CodeS                   ;
  224.     jmp     Addres                  ;
  225. CodeS:  cmp     TEXT0+31,'Y'            ;  scanning required?
  226.     je      Ready                   ;
  227.     cmp     TEXT0+31,'N'            ;  scanning not required?
  228.     jne     ScanD                   ;  bad reply - ask again
  229.     Call    PARMDSK                 ;
  230.     jmp     Diskadr                 ;
  231. ;  Check for drive ready
  232. Ready:  mov     CC0,0                   ;  cylinder number
  233.     mov     HH0,0                   ;  head number (0---1)
  234.     mov     SS0,1                   ;  sector number (1---8)
  235.     Call    SECTOR                  ;  read sector (3 attempts)
  236.     jnc     Attent                  ;  reading successful
  237.     jmp     Error1                  ;  error message
  238. ;  Output message about disk scanning (line 5)
  239. Attent: mov     IOFF,offset I1          ;  address of format list
  240.     DIAM0   TEXT8,1,5,-5,0,0        ;
  241.     mov     IOFF,0                  ;  format list isn't used
  242. ;----------------------------------------------------------
  243. ;  Scanning the diskette to dtermine CC, HH, SS
  244. ;  Determining the number of cyilinders CC
  245. ScanCC: mov     CC0,0                   ;  cylinder number
  246.     mov     HH0,0                   ;  head number (0---1)
  247.     mov     SS0,1                   ;  sector number (0---8)
  248. CyclCC: Call    SECTOR                  ;  read sector (3 attempts)
  249.     jc      ScanHH                  ;  sector hasn't been read
  250.     inc     CC0                     ;  to next cylinder
  251.     jmp     short CyclCC            ;
  252. ;  Determining the number of heads HH
  253. ScanHH: mov     al,CC0
  254.     dec     al                      ;  extra cylinder was read
  255.     mov     NCC0,al                 ;  maximum  cylinder number
  256.     mov     NHH0,0                  ;  maximum head number =0 (one side)
  257.     mov     TEXT4+53,'1'            ;  head number =0 (one side)
  258.     mov     CC0,0                   ;  cylinder number =0
  259.     mov     HH0,1                   ;  head number  = 1 (second side)
  260.     mov     SS0,1                   ;  sector number   =1
  261.     Call    SECTOR                  ;  read sector (3 attempts)
  262.     jc      ScanSS                  ;  sector hasn't been read
  263.     mov     TEXT4+53,'2'            ;  second side (head =1)
  264.     mov     NHH0,1                  ;  maximum head number =1 (two sides)
  265. ;  Determining the number of sectors  SS
  266. ScanSS: mov     CC0,0                   ;  cylinder number =0
  267.     mov     HH0,0                   ;  head number  = 1 (first side)
  268.     mov     SS0,1                   ;  sector number   =1
  269. CyclSS: Call    SECTOR                  ;  read sector (3 attempts)
  270.     jc      Diskparm                ;  next sector hasn't been read
  271.     inc     SS0                     ;  to next cylinder
  272.     jmp     short CyclSS            ;
  273. ;----------------------------------------------------------
  274. ;  Output characteristics of disk read  (CC/HH/SS)
  275. DiskParm:
  276.     CLR     5,24,07h                ;  clear lines  5 --- 24
  277.     mov     al,SS0                  ;
  278.     dec     al                      ;  next number was specified
  279.     mov     NSS0,al                 ;  maximum  sector number
  280.     lea     bp,TEXT4+67             ;  target for edited value
  281.     Call    INTSYM                  ;  convert number of setors
  282.     mov     al,NCC0                 ;  maximum  cylinder number
  283.     inc     al                      ;  cylinders are counted from 0
  284.     lea     bp,TEXT4+38             ;  target for edited value
  285.     Call    INTSYM                  ;  convert number of cylinders
  286.     DIAM0   TEXT4,1,4,-4,0,0        ;
  287. ;----------------------------------------------------------
  288. ;  Ask for cylinder number CC and input that number
  289. Diskadr:mov     VV,39                   ;
  290. GetCC:  DIAM0   TEXT5,3,5,-5,5,VV       ;
  291.     cmp     byte ptr W+1,49h        ;  PgUp ?
  292.     je      JmpAdr                  ;  to preceeding parameter
  293.     cmp     byte ptr W,1Bh          ;  Esc ?
  294.     jne     ConvCC                  ;
  295. JmpAdr: jmp     Addres                  ;
  296. ;  Convert the number of the cylinder  CC
  297. ConvCC: lea     bp,TEXT5+38             ;
  298.     mov     si,2                    ;  counter of source characters
  299.     Call    SYMIN4                  ;  convert SYM --- INT
  300.     mov     CC0,al                  ;
  301.     jnc     ConvHH                  ;
  302.     DIAM0   TEXT7,1,6,-6,0,0        ;  output error message
  303.     jmp     Diskadr                 ;  repeat input
  304. ;  Ask for the head number HH  (0 or 1) and input that number
  305. ConvHH: mov     al,CC0                  ;
  306.     lea     bp,TEXT5+38             ;  target for edited value  CC
  307.     Call    INTSYM                  ;  convert INT ---> SYM
  308.     DIAM0   TEXT5,3,5,-5,5,53       ;
  309.     cmp     byte ptr W+1,49h        ;  PgUp ?
  310.     je      JmpC                    ;
  311.     cmp     byte ptr W,1bh          ;  Esc ?
  312.     jne     ConvH                   ;
  313. JmpC:   jmp     Diskadr                 ;  repeat asking for CC
  314. ;  Convert the head number HH  (0 or 1)
  315. ConvH:  lea     bp,TEXT5+52             ;
  316.     mov     si,2                    ;  counter of source characters
  317.     Call    SYMIN4                  ;  convert SYM --- INT
  318.     mov     HH0,al                  ;
  319.     jc      Goerr                   ;
  320.     cmp     al,1                    ;  head number > 1 requested?
  321.     jng     ConvSS                  ;
  322.     DIAM0   TEXT7,1,6,-6,0,0        ;  output error message
  323. Goerr:  jmp     ConvHH                  ;  output error message
  324. ;  Ask for sector number SS and input that number
  325. ConvSS: DIAM0   TEXT5,3,5,-5,5,68       ;
  326.     cmp     byte ptr W+1,49h        ;  PgUp ?
  327.     je      JmpH                    ;
  328.     cmp     byte ptr W,0Dh          ;  Enter ?
  329.     je      ConvS                   ;
  330.     cmp     byte ptr W,1Bh          ;  Esc ?
  331.     jne     ConvS                   ;
  332. JmpD:   jmp     Diskadr                 ;  ask for cylinder number again
  333. JmpH:   jmp     ConvHH                  ;  ask for head number again
  334. ;  Convert sector number SS
  335. ConvS:  lea     bp,TEXT5+67             ;
  336.     mov     si,2                    ;  counter of source characters
  337.     Call    SYMIN4                  ;  convert SYM --- INT
  338.     mov     SS0,al                  ;
  339.     mov     Count3,3                ;  counter of attempts to read
  340.     jnc     Rdsect                  ;
  341.     DIAM0   TEXT7,1,6,-6,0,0        ;  output error message
  342.     jmp     ConvSS                  ;  repeat parameters input 
  343. ;----------------------------------------------------------
  344. ;  Read the sector (512 bytes) with the number required
  345. Rdsect: Call    SECTOR                  ;  read sevtor required
  346.     jnc     P1                      ;  sector is read succesfully
  347.     lea     si,BUFER                ;  source
  348.     lea     di,TEXT5                ;  target
  349.     mov     cx,Ltext5               ;  length of data transferred
  350.     Call    MOVE                    ;  transfer string of addresses
  351.     jmp     Error1                  ;
  352. ;----------------------------------------------------------
  353. ;  Output sector content onto the screen (lines  5---22)
  354. ;  Editing and output the first page ( 256  bytes)
  355. P1:     lea     si,RDBUF                ;  source data
  356.     lea     bp,Disp1                ;
  357.     Call    SCREEN                  ;  output first 256 bytes
  358.     mov     BUFER+5,'1'             ;  page number
  359.     DIAM1   BUFER,3,5,22,5,39       ;  output buffer onto screen
  360.     lea     si,BUFER                ;  source
  361.     lea     di,TEXT5                ;  target
  362.     mov     cx,Ltext5               ;  length of data transferred
  363.     Call    MOVE                    ;  transfer string of addresses
  364.     lea     di,RDBUF                ;  target data
  365.     Call    MODSECT                 ;  checking for sector modification
  366.     cmp     MOD0,1                  ;  address was modified
  367.     jne     MOD1                    ;
  368.     jmp     Rdsect                  ;  output new sector
  369. MOD1:   Call    MODCHS                  ;  process changed values of CC, HH, SS
  370.     Call    TABUL                   ;  changing disk address
  371. ;  Process keys: Esc, PgDn, PgUp
  372. Esc1:   cmp     byte ptr W,1Bh          ;  Esc ?
  373.     je      JmpBeg                  ;
  374.     cmp     byte ptr W+1,51h        ;  PgDn ?
  375.     je      P2                      ;  output second part of sector
  376.     cmp     byte ptr W+1,49h        ;  PgUp ?
  377.     jne     P2                      ;
  378.     Call    Back                    ;  read backwards
  379.     jmp     Rdsect                  ;  read sector again
  380. JmpBeg: jmp     Diskadr
  381. ;  Editing and output second page (last 256 bytes)
  382. P2:     lea     si,RDBUF+256            ;  source data
  383.     lea     bp,Disp2                ;
  384.     Call    SCREEN                  ;  output last 256 bytes
  385.     mov     BUFER+5,'2'             ;  page number
  386.     DIAM1   BUFER,3,5,22,5,39       ;  output buffer onto screen
  387.     lea     si,BUFER                ;  source
  388.     lea     di,TEXT5                ;  target
  389.     mov     cx,Ltext5               ;  length of data transferred
  390.     Call    MOVE                    ;  transfer string of addresses
  391.     lea     di,RDBUF                ;  target data
  392.     Call    MODSECT                 ;  check for sector mofifying
  393.     cmp     MOD0,1                  ;  sector was modified?
  394.     jne     MOD2                    ;
  395.     jmp     Rdsect                  ;  output new sector
  396. MOD2:   Call    MODCHS                  ;  process changed values of CC, HH, SS
  397.     Call    TABUL                   ;  change disk address
  398. ;  Process keys: Esc, PgDn, PgUp
  399. Esc2:   cmp     byte ptr W,1Bh          ;  Esc ?
  400.     je      JmpBeg                  ;  back to beginning
  401.     cmp     byte ptr W+1,49h        ;  PgUp ?
  402.     jne     PgDn2                   ;
  403.     jmp     P1                      ;
  404. PgDn2:  cmp     byte ptr W+1,51h        ;  PgDn ?
  405.     je      Next2                   ;
  406.     jmp     P2                      ;
  407. Next2:  Call    NEXT                    ;
  408.     jmp     Rdsect                  ;  to processing next sector
  409. ;----------------------------------------------------------
  410. ;  Finish of the program
  411. Exit:    mov    ah,0                    ;  function 0 - set video mode
  412.      mov    al,REG                  ;  restore original video mode
  413.      int    10h                     ;  BIOS video service call
  414.      mov    ax,4C00h                ;  function 4Ch - terminate process
  415.      int    21h                     ;  MS-DOS service call
  416. ;----------------------------------------------------------
  417. ;
  418. ;  Read sector (512 bytes) with the address specified
  419. ;
  420. ;----------------------------------------------------------
  421. SECTOR  PROC    NEAR
  422.     mov     Count3,3                ;  counter of attempts to read
  423. Read3:  xor     ah,ah                   ;  function 00h - reset controller
  424.     int     13h                     ;  BIOS disk service call
  425.     jc      RetS                    ;  exit if error (error code in AH)
  426.     mov     ax,ds                   ;
  427.     mov     es,ax                   ;  ES points to data segment
  428.     lea     bx,RDBUF                ;  address of read buffer
  429.     mov     ch,CC0                  ;  cylinder number
  430.     mov     cl,SS0                  ;  sector number (1---8)
  431.     mov     dh,HH0                  ;  head number (0---1)
  432.     mov     dl,Disk                 ;  disk drive (0 -A, 1 -B...)
  433.     mov     al,1                    ;  number of sectors to read 
  434.     mov     ah,2                    ;  function 02h - read sectors
  435.     int     13h                     ;  BIOS disk service call
  436.     jnc     RetS                    ;  sector was read successfully
  437.     dec     Count3                  ;  decrement counter of attempts
  438.     jg      Read3                   ;  try to read sector again
  439. RetS:   RET                             ;
  440. SECTOR  ENDP
  441. ;  Output error message (error while reading sector in line 6)
  442. Error1: mov     al,ah                   ;  error code
  443.     Call    HEXSYM                  ;  convert HEX ---> SYM
  444.     mov     word ptr TEXT6+33,ax    ;  transfer error code
  445.     mov     al,CC0                  ;
  446.     lea     bp,TEXT6+40             ;  target for edited value
  447.     Call    INTSYM                  ;  convert INT ---> SYM
  448.     mov     al,HH0                  ;
  449.     lea     bp,TEXT6+47             ;  target for edited value
  450.     Call    INTSYM                  ;  convert INT ---> SYM
  451.     mov     al,SS0                  ;
  452.     lea     bp,TEXT6+54             ;  target for edited value
  453.     Call    INTSYM                  ;  convert INT ---> SYM
  454.     mov     IOFF,offset I2          ;
  455.     DIAM0   TEXT6,2,6,-6,0,0        ;  output message
  456.     mov     IOFF,0                  ;
  457.     CLR     5,24,07h                ;  clear screen
  458.     jmp     Addres                  ;  ask for disk address again
  459. ;----------------------------------------------------------
  460. ;
  461. ;  Writing modified sector
  462. ;
  463. ;  Is performed when the cursor is within the data area
  464. ;
  465. ;  and the F3 key has been pressed
  466. ;
  467. ;  DI - address of sector buffer in data segment
  468. ;
  469. ;----------------------------------------------------------
  470. MODSECT  PROC   NEAR
  471.      mov    MOD0,0                  ;  clear modification indicator
  472.      cmp    byte ptr W+1,3Dh        ;  F3 ?
  473.      jne    RetModS                 ;  no, exit
  474.      cmp    byte ptr Q,7            ;  cursor in data area ?
  475.      jl     RetModS                 ;  no, exit
  476.      cmp    byte ptr Q,22           ;  cursor in data area ?
  477.      jg     RetModS                 ;  no, exit
  478.      cmp    byte ptr S,14           ;  cursor in data area ?
  479.      jl     RetModS                 ;  no, exit
  480.      cmp    byte ptr S,72           ;  cursor in data area ?
  481.      jng    C0                      ;  yes
  482. RetModS: RETN                           ;
  483. ;  Transfer modified data into the sector buffer
  484. C0:      PUSHR                          ;
  485.      mov    MOD0,1                  ;  modification indicator
  486.      mov    ax,ds                   ;
  487.      mov    es,ax                   ;  ES points to data segment
  488.      lea    si,BUFER+173            ;  address of screen string beginning
  489.      mov    ADRBUF,si               ;  save address of string
  490.      mov    dx,16                   ;  number of lines output
  491. ;  Outward cycle (16 lines)
  492. C1:      mov    cx,16                   ;  number of elements line
  493. C2:      mov    ax,[si]                 ;  nested cycle starts here
  494.      Call   SYMHEX                  ;  convert:  SYM ---> HEX
  495.      mov    [di],al                 ;  transfer hexadecimal value
  496.      add    si,3                    ;  address of next two bytes
  497.      inc    di                      ;  address of next byte in sector
  498.      loop   C2                      ;  next step of nested cycle
  499. ;  Modify parameters of the outward cycle (to next line)
  500.      mov    si,ADRBUF               ;
  501.      add    si,80                   ;  address of next string
  502.      mov    ADRBUF,si               ;  save address of string
  503.      dec    dx                      ;  number of strings left
  504.      jnz    C1                      ;  to beginning of outward cycle
  505. ;  Writing the modified sector
  506.      mov    Count3,3                ;  counter of attempts to write
  507. Write3:  xor    ah,ah                   ;  function 00h - reset controller
  508.      int    13h                     ;  BIOS disk service call
  509.      mov    ax,ds                   ;
  510.      mov    es,ax                   ;  ES points to data segment
  511.      lea    bx,RDBUF                ;  address of buffer for writing ES:BX
  512.      mov    ch,CC0                  ;  cylinder number
  513.      mov    cl,SS0                  ;  sector number (1---8)
  514.      mov    dh,HH0                  ;  head number (0---1)
  515.      mov    dl,Disk                 ;  disk drive (0 -A, 1 -B...)
  516.      mov    al,1                    ;  number of sectors to write
  517.      mov    ah,3                    ;  function 03h - write sectors
  518.      int    13h                     ;  BIOS disk service call
  519.      jnc    Retwr                   ;  sector has been written 
  520.      dec    Count3                  ;  decrease number of attempts
  521.      jg     Write3                  ;  try to write again
  522.      jmp    short Error2            ;  error while writing sector
  523. Retwr:   POPR                           ;
  524.      RETN                           ;
  525. ;  Output message "error while writing sector" (line =6)
  526. Error2:  mov    al,ah                   ;  error code
  527.      Call   HEXSYM                  ;  convert HEX ---> SYM
  528.      mov    word ptr TEXT9+33,ax    ;  transfer eror code
  529.      mov    al,CC0                  ;
  530.      lea    bp,TEXT9+40             ;  target for edited data
  531.      Call   INTSYM                  ;  convert INT ---> SYM
  532.      mov    al,HH0                  ;
  533.      lea    bp,TEXT9+47             ;  target for edited data
  534.      Call   INTSYM                  ;  convert INT ---> SYM
  535.      mov    al,SS0                  ;
  536.      lea    bp,TEXT9+54             ;  target for edited data
  537.      Call   INTSYM                  ;  convert INT ---> SYM
  538.      mov    IOFF,offset I2          ;
  539.      DIAM0  TEXT9,2,6,-6,0,0        ;  output message
  540.      mov    IOFF,0                  ;
  541.      CLR    6,6,07h                 ;  clear string
  542.      POPR                           ;
  543.      RETN                           ;
  544. MODSECT  ENDP
  545. ;----------------------------------------------------------
  546. ;
  547. ;  To process the next sector
  548. ;
  549. ;----------------------------------------------------------
  550. ;  Increase the sector number by 1
  551. NEXT    PROC    NEAR
  552.     mov     al,SS0                  ;  preceeding sector number
  553.     inc     al                      ;  number of next sector
  554.     cmp     al,NSS0                 ;  to other side?
  555.     jg      ModHH                   ;
  556.     mov     SS0,al                  ;  transfer number of next sector
  557.     jmp     RetM                    ;  to processing next sector
  558. ;  Increase the head number by 1
  559. ModHH:  mov     SS0,1                   ;  first sector of next cylinder
  560.     mov     al,HH0                  ;  number of head (side) processed
  561.     inc     al                      ;  number of next head
  562.     cmp     al,NHH0                 ;  to next cylinder?
  563.     jg      ModCC                   ;
  564.     mov     HH0,al                  ;  transfer number of next head
  565.     jmp     RetM                    ;  to processing next sector
  566. ;  Increase the cylinder number by 1
  567. ModCC:  mov     SS0,1                   ;  first sector of next cylinder
  568.     mov     HH0,0                   ;  initial head number =1
  569.     mov     al,CC0                  ;  number of preceeding cylinder
  570.     inc     al                      ;  number of next cylinder
  571.     cmp     al,NCC0                 ;  all cylinders processed ?
  572.     jg      RetM                    ;  yes, not move
  573.     mov     CC0,al                  ;  transfer number of next cylinder
  574. RetM:   RETN
  575. NEXT    ENDP
  576. ;----------------------------------------------------------
  577. ;
  578. ;   Reading disk sectors backwards
  579. ;
  580. ;----------------------------------------------------------
  581. BACK     PROC   NEAR
  582. ;  decreasing sector number by 1
  583. DecSS:   mov    al,SS0                  ;  sector number
  584.      dec    al                      ;  preceeding sector number
  585.      cmp    al,1                    ;  to preceeding cylinder?
  586.      jl     DecHH                   ;
  587.      mov    SS0,al                  ;  transfer preceeding sector number
  588.      jmp    Retb                    ;  to processing preceeding sector
  589. ;  decreasing head number by 1
  590. DecHH:   mov    SS0,1                   ;  initial sector number =1
  591.      mov    al,HH0                  ;  number of current head
  592.      dec    al                      ;  number of preceeding head
  593.      jl     DecCC                   ;
  594.      mov    HH0,al                  ;  transfer number of preceeding head
  595.      jmp    Retb                    ;  to processing preceeding sector
  596. ;  decreasing cylinder number by 1
  597. DecCC:   mov    SS0,1                   ;  first sector of preceeding cylinder
  598.      mov    HH0,0                   ;  initial head number =0
  599.      mov    al,CC0                  ;  number of current cylinder
  600.      dec    al                      ;  number of preceeding cylinder
  601.      jl     Retb                    ;
  602.      mov    CC0,al                  ;  transfer number of prec. cylinder
  603. Retb:    RETN
  604. BACK     ENDP
  605. ;----------------------------------------------------------
  606. ;
  607. ;  Subroutine for converting an integer number into character string
  608. ;
  609. ;  AL  - source number (is converted to a word)
  610. ;
  611. ;  BP  - address of output character string
  612. ;
  613. ;----------------------------------------------------------
  614. INTSYM  PROC    NEAR
  615.     cbw                             ;  convert byte to word
  616.     xor     dx,dx                   ;  high part =0
  617.     mov     si,2                    ;  number of character in result
  618.     Call    INSYM4                  ;  convert integer
  619.     cmp     byte ptr DS:[bp],' '    ;  suppressed zero present?
  620.     jne     Retint                  ;
  621.     mov     byte ptr DS:[bp],'0'    ;  put leading zero
  622. Retint: RETN
  623. INTSYM  ENDP
  624. ;----------------------------------------------------------
  625. ;
  626. ;  Subroutine for creating the display buffer (256 bytes)
  627. ;
  628. ;  SI  - address of sector buffer
  629. ;
  630. ;  BP  - address of Displacement Table
  631. ;
  632. ;----------------------------------------------------------
  633. SCREEN   PROC   NEAR
  634.      PUSHR                          ;  save all registers
  635.      PUSHR  <si,bp>                 ;
  636.      SPACE  BUFER,2000              ;  clear screen buffer
  637.      lea    si,TEXT5                ;  source
  638.      lea    di,BUFER                ;  target
  639.      mov    cx,Ltext5               ;  length of data transferred
  640.      Call   MOVE                    ;  transfer string of addresses
  641. ;  Create disk addresses (line =5)
  642.      mov    al,CC0                  ;  address of cylinder
  643.      lea    bp,BUFER+38             ;  target for edited value
  644.      Call   INTSYM                  ;  convert INT --- SYM
  645.      mov    al,HH0                  ;  address of head
  646.      lea    bp,BUFER+52             ;  target for edited value
  647.      Call   INTSYM                  ;  convert INT --- SYM
  648.      mov    al,SS0                  ;  number of sector
  649.      lea    bp,BUFER+67             ;  target for edited value
  650.      Call   INTSYM                  ;  convert INT --- SYM
  651. ;  Create header (line 6)
  652.      lea    si,TXT0                 ;  source
  653.      lea    di,BUFER+80             ;  target
  654.      mov    cx,80                   ;  length of data transferred
  655.      Call   MOVE                    ;  transfer header
  656.      POPR   <bp,si>                 ;
  657.      lea    di,BUFER+160            ;  address of screen string beginning
  658.      mov    ADRBUF,di               ;  save address of string
  659.      mov    dx,16                   ;  number of lines on screen
  660. ;  Outward cycle (16 lines)
  661. S0:      PUSHR  <si,di>                 ;
  662.      inc    di                      ;  target
  663.      mov    si,bp                   ;  source
  664.      mov    cx,10                   ;  length of data transferred
  665.      Call   MOVE                    ;  transfer margins
  666.      POPR   <di,si>                 ;
  667.      mov    cx,16                   ;  number of characters in line
  668.      mov    bx,di                   ;  save address of string
  669. ;  Nested cycle (16 bytes)
  670. S1:      mov    al,[si]                 ;  start of nested cycle
  671.      Call   HEXSYM                  ;  convert: HEX ---> SYM
  672.      mov    DS:[di+13],ax           ;  transfer hexadecimal value
  673.      mov    al,[si]                 ;  ASCII character
  674.      cmp    al,1bh                  ;  Esc ?
  675.      jg     S2                      ;
  676.      mov    al,20h
  677. S2:      mov    [bx+63],al              ;  transfer ASCII character
  678.      add    di,3                    ;  address of next pair of byte
  679.      inc    bx                      ;  address of next ASCII character
  680.      inc    si                      ;  address of byte in sector
  681.      loop   S1                      ;  to repeat of nested cycle
  682. ;  Modify parameters of the outward cycle (to the next line)
  683.      mov    di,ADRBUF               ;
  684.      add    di,80                   ;  address of next string
  685.      mov    ADRBUF,di               ;  save address of string
  686.      add    bp,10                   ;  address of next element
  687.      dec    dx                      ;  number of strings left
  688.      jnz    S0                      ;  to beginning of outward cycle
  689. ;  Put edited addresses into the string  TEXT5
  690.      lea    si,BUFER                ;  source
  691.      lea    di,TEXT5                ;  target
  692.      mov    cx,Ltext5               ;  length of data transferred
  693.      Call   MOVE                    ;  transfer string of addresses
  694.      POPR                           ;
  695.      RETN                           ;
  696. SCREEN   ENDP
  697. ;----------------------------------------------------------
  698. ;
  699. ;  Change the disk address (the Enter key)
  700. ;
  701. ;----------------------------------------------------------
  702. TABUL   PROC    NEAR
  703.     cmp     byte ptr W,0Dh          ;  Enter ?
  704.     je      SS39                    ;
  705.     RETN
  706. SS39:   pop     ax                      ;  restore stack
  707.     cmp     S,39                    ;  cursor at cylinder position ?
  708.     je      VV53                    ;  set at the head position and repeat
  709.     cmp     S,41                    ;  cursor at cylinder position ?
  710.     ja      SS53                    ;
  711. VV53:   jmp     ConvHH                  ;  repeat output (cursor at  HH)
  712. ;  Check wheteher the cursor is located in head position (jump to sector)
  713. SS53:   cmp     S,53                    ;  cursor at head position ?
  714.     je      VV68                    ;
  715.     cmp     S,54                    ;  cursor at head position ?
  716.     jne     SS68                    ;
  717. VV68:   jmp     ConvSS                  ;  repeat output (cursor at  SS)
  718. SS68:   jmp     Diskadr                 ;  repeat output (cursor at  CC)
  719. TABUL   ENDP
  720. ;----------------------------------------------------------
  721. ;
  722. ;   Subroutine for processing athe sector number
  723. ;
  724. ;----------------------------------------------------------
  725. MODCHS   PROC   NEAR
  726.      lea    bp,BUFER+38             ;  value of cylinder number  CC
  727.      mov    si,2                    ;  counter of source characters
  728.      Call   SYMIN4                  ;  convert SYM --- INT
  729.      mov    CC0,al                  ;  new value of cylinder number
  730.      lea    bp,BUFER+52             ;  value of head number  HH
  731.      mov    si,2                    ;  counter of source characters
  732.      Call   SYMIN4                  ;  convert SYM --- INT
  733.      mov    HH0,al                  ;  new value of head number
  734.      lea    bp,BUFER+67             ;  value of sector number  SS
  735.      mov    si,2                    ;  counter of source characters
  736.      Call   SYMIN4                  ;  convert SYM --- INT
  737.      mov    SS0,al                  ;  new value of sector number
  738. Retmod:  RET
  739. MODCHS   ENDP
  740. ;----------------------------------------------------------
  741. ;
  742. ;   Ask for diskette parameters (CC, HH, SS)
  743. ;
  744. ;----------------------------------------------------------
  745. PARMDSK  PROC   NEAR
  746. InpCHS:  DIAM0  TEXT1,3,5,-5,5,39       ;
  747.      lea    bp,TEXT1+38             ;  value of cylinder number  CC
  748.      mov    si,2                    ;  counter of source characters
  749.      Call   SYMIN4                  ;  convert SYM --- INT
  750.      dec    al                      ;  cylinder number : 0 --- 80
  751.      mov    NCC0,al                 ;  maximum  cylinder number
  752.      jnc    InpHH                   ;
  753.      DIAM0  TEXT7,1,6,-6,0,0        ;  output error message
  754.      jmp    InpCHS                  ;  repeat input
  755. ;
  756. InpHH:   DIAM0  TEXT1,3,5,-5,5,53       ;
  757.      lea    bp,TEXT1+52             ;  value of head number  HH
  758.      mov    si,2                    ;  counter of source characters
  759.      Call   SYMIN4                  ;  convert SYM --- INT
  760.      dec    al                      ;
  761.      mov    NHH0,al                 ;  maximum  head number
  762.      jnc    InpSS
  763.      DIAM0  TEXT7,1,6,-6,0,0        ;  output error message
  764.      jmp    InpHH                   ;  repeat input
  765. ;
  766. InpSS:   DIAM0  TEXT1,3,5,-5,5,68       ;
  767.      lea    bp,TEXT1+67             ;  value of sector number  SS
  768.      mov    si,2                    ;  counter of source characters
  769.      Call   SYMIN4                  ;  convert SYM --- INT
  770.      mov    NSS0,al                 ;  maximum  sector number
  771.      jnc    RetCHS
  772.      DIAM0  TEXT7,1,6,-6,0,0        ;  output error message
  773.      jmp    InpSS                   ;  repeat input
  774. RetCHS:  RET
  775. PARMDSK  ENDP
  776.      END
  777.